package demo.service;

import demo.Result;
import demo.entity.User;
import demo.entity.UserCompany;
import demo.repository.CompanyRepository;
import demo.repository.DepartmentRepository;
import demo.repository.UserCompanyRepository;
import demo.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.security.SecurityProperties;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

/**
 * 工作经历 Service
 *
 * @author 何宇昕
 * @version 1.8
 */
@Service
public class UserCompanyService {
    @Autowired
    UserCompanyRepository userCompanyRepository;
    @Autowired
    UserRepository userRepository;
    @Autowired
    CompanyRepository companyRepository;
    @Autowired
    DepartmentRepository departmentRepository;

    /**
     * 添加 员工-公司-部门 记录
     *
     * @param userCompany 员工-公司-部门 记录
     * @return 提示信息
     */
    public Result update(UserCompany userCompany, Boolean adding) {
        // 0. 当用户或公司或部门不存在时
        if (userRepository.findUserByUid(userCompany.getUid()) == null) {
            return Result.error("用户不存在");
        }
        if (companyRepository.findCompanyByCompanyId(userCompany.getCompanyId()) == null) {
            return Result.error("公司不存在");
        }
        if (departmentRepository.findDepartmentByDepartmentId(userCompany.getDepartmentId()) == null) {
            return Result.error("部门不存在");
        }

        UserCompany last = userCompanyRepository.findUserCompanyByEndTimeIsNullAndUid(userCompany.getUid());
        // 1. 当 user_company 中不存在该用户的任何记录
        // or 2. 当用户已经离职
        if (userCompanyRepository.findUserCompanyByEndTimeIsNullAndUid(userCompany.getUid()) == null
            || userCompanyRepository.findUserCompaniesByUid(userCompany.getUid()).isEmpty()) {
            if (adding) {
                userCompany.setBeginTime(new Date());
                userCompanyRepository.save(userCompany);
                return Result.success("用户工作信息保存成功", userCompany);
            }
            throw new RuntimeException("异常：尝试在添加员工时不输入邀请码");
        }
        if (adding) {
            throw new RuntimeException("异常：尝试在修改员工信息时输入邀请码");
        }
        // 3. 当用户未离职
        if (last != null) {
            // 如果仅修改工号，不插入新数据，直接在原有数据上修改
            if (last.getDepartmentId().equals(userCompany.getDepartmentId())
                && last.getPosition().equals(userCompany.getPosition())
                && !last.getWorkId().equals(userCompany.getWorkId())
            ) {
                last.setWorkId(userCompany.getWorkId());
                userCompanyRepository.save(last);
                return Result.success("用户工作信息保存成功", last);
            }

            // 如果工号、职位和部门均未变更，则不修改
            if (last.getDepartmentId().equals(userCompany.getDepartmentId())
                && last.getPosition().equals(userCompany.getPosition())
            ) {
                return Result.error("用户工作信息没有变更");
            }

            Date date = new Date();
            last.setEndTime(date);
            userCompanyRepository.save(last);
            userCompany.setBeginTime(date);
            userCompanyRepository.save(userCompany);
        }
        return Result.success("用户工作信息保存成功", userCompany);
    }

    /**
     * 按 公司 id 列出所有工作经历
     *
     * @param companyId 公司 id
     * @return 工作经历的对象的数组
     */
    public List<UserCompany> listUserCompanies(Long companyId) {
        return userCompanyRepository.findUserCompanyByEndTimeIsNullAndCompanyId(companyId);
    }

    /**
     * 按 用户 uid 列出所有工作经历
     *
     * @param user 用户对象
     * @return 工作经历的对象的数组
     */
    public List<UserCompany> listUserCompanies(User user) {
        return userCompanyRepository.findUserCompaniesByUid(user.getUid());
    }

    /**
     * 列出最新的工作经历
     *
     * @return 工作经历的对象的数组
     */
    public List<UserCompany> listLatestUserCompanies() {
        return userCompanyRepository.findUserCompanyByEndTimeIsNull();
    }

    /**
     * 按 用户 id 查找记录
     *
     * @param uid 用户 id
     * @return 关系对象
     */
    public List<UserCompany> findUserCompaniesByUid(Long uid) {
        return userCompanyRepository.findUserCompaniesByUid(uid);
    }

    /**
     * 按 用户 id 查找员工工作经历
     *
     * @param uid 用户 id
     * @return 当员工不在职时返回错误结果对象，当员工在职时返回正确结果对象，包含工作经历对象
     */
    public Result findLatestUserCompanyByUid(Long uid) {
        UserCompany userCompany = userCompanyRepository.findUserCompanyByEndTimeIsNullAndUid(uid);
        if (userCompany == null) {
            return Result.error("员工不在职。");
        }
        return Result.success("员工在职，并找到了最新的一条工作经历", userCompany);
    }

    public List<UserCompany> findLatestUserCompanyByDepartmentId(Long departmentId) {
        return userCompanyRepository.findUserCompaniesByEndTimeIsNullAndDepartmentId(departmentId);
    }

    /**
     * 按 工号、公司 id、员工 id 判断是否可以修改员工的工号
     *
     * @param userCompany 工作经历对象
     * @return 结果对象
     */
    public Result isWorkIdExist(UserCompany userCompany) {
        Long workId = userCompany.getWorkId();
        Long uid = userCompany.getUid();
        Long companyId = userCompany.getCompanyId();
        List<UserCompany> userCompaniesOfUid = userCompanyRepository.findUserCompanyByUidAndEndTimeIsNull(uid);
        List<UserCompany> userCompaniesToAssign = userCompanyRepository.findUserCompanyByEndTimeIsNullAndCompanyIdAndWorkId(companyId, workId);

        if (!userCompaniesOfUid.isEmpty() && userCompaniesOfUid.get(0).getWorkId().equals(workId)) {
            return Result.success("工号可以修改");
        }

        if (!userCompaniesToAssign.isEmpty()) {
            return Result.error("工号已分配");
        }

        return Result.success("工号未分配");
    }

    /**
     * 按 工号 和 公司 id 搜索工号是否存在（在添加员工时使用）
     *
     * @param workId    工号
     * @param companyId 公司 id
     * @return 结果对象
     */
    public Result isWorkIdExistWhenRecruit(Long workId, Long companyId) {
        List<UserCompany> userCompaniesToAssign = userCompanyRepository.findUserCompanyByEndTimeIsNullAndCompanyIdAndWorkId(companyId, workId);

        if (!userCompaniesToAssign.isEmpty()) {
            return Result.error("工号已分配");
        }

        return Result.success("工号未分配");
    }

    /**
     * 搜索工作记录
     *
     * @param userCompany 工作记录对象，需要包含工作经历的 id
     * @return 结果对象
     */
    public Result isUserCompanyExist(UserCompany userCompany) {
        if (userCompanyRepository.existsById(userCompany.getId())) {
            return Result.success("工作记录查找成功");
        }
        return Result.error("工作记录不存在");
    }


    /**
     * 按部门 id 统计部门人数
     *
     * @param departmentId 部门 id
     * @return 结果对象，包含部门人数
     */
    public Result countEmployeesByDepartmentId(Long departmentId) {
        return Result.success("查询部门人数成功", userCompanyRepository.countAllByDepartmentIdAndEndTimeIsNull(departmentId));
    }

    /**
     * 移除员工
     *
     * @param uid 用户 id
     * @param reason 离职理由
     * @return 结果对象
     */
    public Result deleteEmployee(Long uid, String reason) {

        Result result = findLatestUserCompanyByUid(uid);
        if (result.getCode() != 200) {
            return Result.error("用户不在职，无法移除员工");
        }

        UserCompany userCompany = (UserCompany) result.getData();
        userCompany.setReason(reason);
        userCompany.setEndTime(new Date());
        userCompanyRepository.save(userCompany);
        return Result.success("移除员工成功");
    }

    /**
     * 按 公司 id 和 职位 查找最新工作记录
     *
     * @param companyId 公司 id
     * @param position 职位
     * @return
     */
    public Result listEmployeesByPosition(Long companyId, String position) {
        List<UserCompany> userCompanies = userCompanyRepository.findUserCompaniesByEndTimeIsNullAndCompanyIdAndPosition(companyId, position);
        if (userCompanies.isEmpty()) {
            return Result.error("没有查询到任何有关该公司的数据");
        }
        return Result.success("查询成功", userCompanies);
    }
}
